package helperx

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"hash/crc32"
	"math/rand"
	"time"

	"gorm.io/gorm"
)

// EasyMD5 获取md5
func EasyMD5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

// EasyMD5Half 获取md5 16位
func EasyMD5Half(str string) string {
	return EasyMD5(str)[8:24]
}

// EasyHmacSha256 hash_hmac sha256
func EasyHmacSha256(str string, key string) string {
	hashKey := []byte(key)
	h := hmac.New(sha256.New, hashKey)
	h.Write([]byte(str))
	sign := hex.EncodeToString(h.Sum(nil))
	return sign
}

// EasySHA1 获取sha1
func EasySHA1(str string) string {
	h := sha1.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum([]byte(nil)))
}

// EasyCRC32 获取crc32
func EasyCRC32(str string) uint32 {
	return crc32.ChecksumIEEE([]byte(str))
}

// RandomString 获取随机子串
func RandomString(l int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyz"
	bytes := []byte(str)
	result := make([]byte, 0)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

// StringInArray 字符串包含
func StringInArray(need string, needArr []string) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

// IntInArray 数值包含
func IntInArray(need int, needArr []int) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

// ChunkStringSlice 拆分
func ChunkStringSlice(slice []string, chunkSize int) [][]string {
	var chunks [][]string
	for i := 0; i < len(slice); i += chunkSize {
		end := i + chunkSize

		// necessary check to avoid slicing beyond
		// slice capacity
		if end > len(slice) {
			end = len(slice)
		}

		chunks = append(chunks, slice[i:end])
	}

	return chunks
}

// ChunkIntSlice 拆分
func ChunkIntSlice(slice []int, chunkSize int) [][]int {
	var chunks [][]int
	for i := 0; i < len(slice); i += chunkSize {
		end := i + chunkSize

		// necessary check to avoid slicing beyond
		// slice capacity
		if end > len(slice) {
			end = len(slice)
		}

		chunks = append(chunks, slice[i:end])
	}

	return chunks
}

// IfThen 模拟三元运算
// someString := IfThen(1 > 2, "It's true", "It's false").(string)
// someInt := IfThen(1 > 2, 1, 2).(int)
// someInt64 := IfThen(1 > 2, int64(1), int64(2)).(int64)
// 入参需要注意空指针如：
// IfThen(a == nil, "", a.Name)，a为nil的时候，参数3会panic
func IfThen(cond bool, yup, nope interface{}) interface{} {
	if cond {
		return yup
	}

	return nope
}

// IsGormNotFound gorm v2版本，判断错误是否为 RecordNotFound
// 需要确保当前使用的gorm是v2版本
func IsGormNotFound(err error) bool {
	return errors.Is(err, gorm.ErrRecordNotFound)
}
